package com.chapter.sample.redis.boolmfilter;

import ch.qos.logback.core.util.TimeUtil;
import lombok.extern.slf4j.Slf4j;
import org.redisson.Redisson;
import org.redisson.api.RBloomFilter;
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.redisson.client.codec.StringCodec;
import org.redisson.config.Config;

import java.util.concurrent.TimeUnit;

/**
 * redis 布隆过滤器
 */
@Slf4j
public class RedissonBloomFilter {
    //1、定义一个常量
    public static final int _1W = 10000;
    //2、定义guava布隆过滤器,初始容量
    public static final int SIZE = 100 * _1W;
    //3、误判率，它越小误判的个数也就越少(思考,是否可以无限小?? 没有误判岂不是更好)
    public static double fpp = 0.03;

    static RedissonClient redissonClient;
    static RBloomFilter rBloomFilter;//redis版内置的布隆过滤器


    static {
        Config config = new Config();
        config.useSingleServer().setAddress("redis://127.0.0.1:6379").setDatabase(0);
        redissonClient = Redisson.create(config);

        rBloomFilter = redissonClient.getBloomFilter("phoneListBloomFilter", new StringCodec());
        rBloomFilter.tryInit(SIZE, fpp);

        //1、测试 布隆过滤器有 + redis有
        //rBloomFilter.add("10086");
        //redissonClient.getBucket("10086", new StringCodec()).set("chinamobile10086");

        //2、测试 布隆过滤器有 + redis无
        //rBloomFilter.add("10087");

        //3、测试，布隆过滤器无 + redis无
    }

    private static String getPhoneListById(String number) {
        String result = null;
        if (number == null) {
            return null;
        }
        //1、先去布隆过滤器里面查询
        if (rBloomFilter.contains(number)) {
            //2、布隆过滤器里有，再去redis里面查询
            RBucket<String> rBucket = redissonClient.getBucket(number, new StringCodec());
            result = rBucket.get();
            if (result != null) {
                return "i com from redis: " + result;
            }
            result = getPhoneListByMySQL(number);
            if (result == null) {
                return null;
            }
            //重写将数据更新回redis
            redissonClient.getBucket(number, new StringCodec()).set(result);
            return "i com from MySQL: " + result;
        }
        return result;
    }

    private static String getPhoneListByMySQL(String number) {
        return "chinamobile" + number;
    }

    public static void main(String[] args) throws InterruptedException {
        //String phoneListById = getPhoneListById("10086");
        //String phoneListById = getPhoneListById("10087");
        String phoneListById = getPhoneListById("10088");
        System.out.println("---------查询出来的结果：" + phoneListById);

        TimeUnit.SECONDS.sleep(1);
        redissonClient.shutdown();
    }


}
